from pymongo import MongoClient, ASCENDING, DESCENDING
#1. 传入数据库IP和端口号
mc = MongoClient('127.0.0.1', 27017)
#2. 直接传入连接字串
# mc = MongoClient('mongodb://127.0.0.1:27017')
# 有密码的连接
# 首先指定连接testdb数据库
# db = mc.testdb
# 通过authenticate方法认证账号密码
# db.authenticate('username','password')
# 检查是否连接成功，输出以下结果表示连接成功
# print(mc.server_info())

# 指定操作数据库的两种方式
#1. 获取 testdb 数据库，没有则自动创建
db = mc.testdb
#2. 效果与上面 db = mc.testdb 相同
# db = mc['testdb']
# 打印出testdb数据库下所有集合(表)
# print(db.collection_names())


# 指定操作集合的两种方式
#1. 获取 test 集合，没有则自动创建
# collection = db.test

#2. 效果与 collection = db.test 相同
collection = db['test']


# 向集合中插入一条记录
# book = {
#       'name' : 'Python基础',
#       'author' : '张三',
#       'page' : 80
# }
# collection.insert_one(book)
# 对于insert_many()方法，我们可以将数据以列表形式传递参数
# book1 = {
#       'name' : 'Java基础',
#       'author' : '李白',
#       'page' : 100
# }
# book2 = {
#       'name' : 'Java虚拟机',
#       'author' : '王五',
#       'page' : 100
# }
# # 创建 book_list 列表
# book_list = [book1, book2]
# # 向集合中插入多条记录
# collection.insert_many(book_list)
# 打印集合中一行数据 print(collection.find_one())
# 循环打印集合所有行
# list = collection.find();
# for i in list:
#     print(i)

# TOdo 数据的查询操作
# 通过条件查询一条记录，如果不存在则返回None
# res = collection.find_one({'author': '王五'})
# print(res)

# 通过条件查询多条记录，如果不存在则返回None
# res = collection.find({'page': 100})
# # 遍历对象，并打印查询结果
# for r in res:
#    print(r)


# 查询page大于50的记录
# res = collection.find({'page': {'$gt': 50}})
# for r in res:
#    print(r)

'''
符号	含义	举例
$gt	    大于	{‘page’: {‘$gt’: 50}
$lt	    小于	 
$lte	小于等于	 
$gte	大于等于	 
$ne	    不等于	 
$in	    在范围内	{‘page’: {‘$in’: [50, 100]}}
$nin	不在范围内	{‘page’: {‘$nin’: [50, 100]}}
$regex	匹配正则表达式	{‘name’: {‘$regex’: ‘^张.*’}}
$exists	属性是否存在	{‘name’: {‘$exists’: True}}
$type	类型判断	{‘name’: {‘$type’: ‘string’}}
$mod	数字模操作	{‘page’: {‘$mod’: [80, 10]}}
$text	文本查询	{‘$text’: {‘$search’: ‘Java’}}
$where	高级条件查询	{‘$where’: ‘obj. author == obj. full_name’}
'''

# todo 数据的更新操作
# 查询一条记录
# book = collection.find_one({'author': '张三'})
# book['page'] = 90
# 更新满足条件{'author', '张三'}的第一条记录
# res = collection.update_one({'author': '张三'}, {'$set': book})

# 更新返回结果是一个对象，我们可以调用matched_count和modified_count属性分别获得匹配的数据条数和影响的数据条数。
# print(res.matched_count, res.modified_count)

# 更新满足条件 page>90 的所有记录，page 字段自加 10
# res = collection.update_many({'page': {'$gt': 90}}, {'$inc': {'page': 10}})
# # # 打印更新匹配和影响的记录数
# # print(res.matched_count, res.modified_count)

# book3 = {'name':'Python高级', 'author':'赵飞', 'page': 50}

# upsert=True表示如果没有满足更新条件的记录，则会将book3插入集合中
# res = collection.update_one({'author': '赵飞'}, {'$set': book3}, upsert=True)
# print(res.matched_count, res.modified_count)
#打印结果：0 0

# 查询所有记录，并遍历打印出来
# res = collection.find()
# for r in res:
#    print(r)

# todo 集合的删除操作
# 删除满足条件的第一条记录
# result = collection.delete_one({'author': '张三'})
# 同样可以通过返回对象的 deleted_count 属性查询删除的记录数
# print(result.deleted_count)

# 删除满足条件的所有记录，以下为删除 page < 90 的记录
# result = collection.delete_many({'page': {'$lt': 90}})
# print(result.deleted_count)

# todo 其他数据库操作  注意：在数据量在千万、亿级别庞大的时候，查询时最好 skip() 的值不要太大，这样很可能导致内存溢出。
# 查询返回满足条件的记录然后删除
# result = collection.find_one_and_delete({'author': '王五'})
# print(result)
# 统计查询结果个数
# 全部结果个数
# count = collection.find().count()
# print('集合元素总数:%s' % count)

# 查询结果按字段排序
# 升序
# results = collection.find().sort('page', ASCENDING)

# 降序
# results = collection.find().sort('page', DESCENDING)


# 下面查询结果是按page升序排序，只返回第二条记录及以后的两条结果
# results = collection.find().sort('page', ASCENDING).skip(1).limit(2)
# for r in results:
#    print(r)

# todo 数据索引操作

# unique=True时，创建一个唯一索引，索引字段插入相同值时会自动报错，默认为False
# collection.create_index('page', unique= True)
# # 打印结果：'page_1'
#
# # 打印出已创建的索引
# print(collection.index_information())

# 删除索引
# collection.drop_index('page_1')

#删除集合
# collection.drop()

# pymongo文档：https://pymongo.readthedocs.io/en/stable/